package com.hst.capacity.application.export.impl;

import com.alibaba.fastjson2.JSON;
import com.hst.capacity.application.export.XssfImporter;
import com.hst.capacity.domain.common.constants.AliTripTransferConstants;
import com.hst.capacity.domain.common.constants.Constants;
import com.hst.capacity.domain.common.constants.TongChengConstants;
import com.hst.capacity.domain.exception.BusinessException;
import com.hst.capacity.domain.model.entity.account.FinanceCheckTmpEntity;
import com.hst.capacity.infra.persistence.mybatis.FinanceMapper;
import com.hst.capacity.infra.util.DateUtil;
import com.hst.capacity.infra.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class XssfImporterImpl implements XssfImporter {

    @Autowired
    FinanceMapper financeDAO;

    @Override
    public void importAccountData(MultipartFile file, int type) {

        String originalFileName = file.getOriginalFilename();
        try {

            byte[] uploadBytes = file.getBytes();
            ByteArrayInputStream byteInputStream = new ByteArrayInputStream(uploadBytes);
            Workbook wb = new XSSFWorkbook(byteInputStream);

            List<FinanceCheckTmpEntity> dataLst = null;

            switch (type) {
                case Constants.OrderSource.ALITRIP: {
                    log.info("飞猪对账单");
                    dataLst = this.AliTripVoucherExcel(wb);
                    if (dataLst == null)
                        log.info("飞猪对账单解析数据为空");
                    else
                        log.info("飞猪对账单数据:{}", JSON.toJSONString(dataLst));
                    break;
                }
                case Constants.OrderSource.TONGCHENG_RIDE:
                    dataLst = this.TcRideVoucherExcel(wb);
                    break;
                default:
                    //dataLst = this.AliTripVoucherExcel(wb);
                    break;
            }

            //对账数据删除
            financeDAO.deleteCheckTmp();
            financeDAO.insertCheckTmp(dataLst);
            financeDAO.checkFinanceOK();
            financeDAO.checkFinanceNG();

            if(type==Constants.OrderSource.ALITRIP){
                //第三方订单号更新
                financeDAO.updateCheckTmp();
                //订单审核状态更新
                financeDAO.SetOrderCheckStatusFlyPig();
                //订单审核状态更新
                financeDAO.SetOrderCheckStatusIcFlyPig();
                //订单审核状态更新
                financeDAO.SetOrderCheckStatusExFlyPig();
            }else{
                //订单审核状态更新
                financeDAO.SetOrderCheckStatus();
                //订单审核状态更新
                financeDAO.SetOrderCheckStatusIc();
                //订单审核状态更新
                financeDAO.SetOrderCheckStatusEx();
            }
            //订单审核状态更新
            financeDAO.insert_user_account_statement(originalFileName);
            //订单审核状态更新
            financeDAO.insert_user_account_statement_Ic(originalFileName);
            //订单审核状态更新
            financeDAO.insert_user_account_statement_Ex(originalFileName);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private List<FinanceCheckTmpEntity> AliTripVoucherExcel(Workbook wb) {

        Row row = null;
        Sheet sheet = null;
        String cellData = null;

        List<FinanceCheckTmpEntity> list = new ArrayList<FinanceCheckTmpEntity>();
        if (wb != null) {
            //获取第一个sheet
            sheet = wb.getSheetAt(0);
            //获取最大行数
            int rowMax = sheet.getPhysicalNumberOfRows();
            //获取第一行
            row = sheet.getRow(0);
            //获取最大列数
            int colMax = row.getPhysicalNumberOfCells();

            HashMap<String, Integer> tempValue = new HashMap<>();
            for (int j = 0; j < colMax; j++) {
                row = sheet.getRow(0);
                cellData = String.valueOf(row.getCell(j));

                if (cellData.equals(AliTripTransferConstants.AliTripVoucherExcelHeader.Entry_Time)) {
                    //入账时间
                    tempValue.put(AliTripTransferConstants.AliTripVoucherExcelHeader.Entry_Time, j);
                } else if (cellData.equals(AliTripTransferConstants.AliTripVoucherExcelHeader.Alipay_Transaction_Number)) {
                    //支付宝交易号
                    tempValue.put(AliTripTransferConstants.AliTripVoucherExcelHeader.Alipay_Transaction_Number, j);
                } else if (cellData.equals(AliTripTransferConstants.AliTripVoucherExcelHeader.Accounting_Type)) {
                    //账务类型
                    tempValue.put(AliTripTransferConstants.AliTripVoucherExcelHeader.Accounting_Type, j);
                } else if (cellData.equals(AliTripTransferConstants.AliTripVoucherExcelHeader.Income_Yuan) ||
                        cellData.equals(AliTripTransferConstants.AliTripVoucherExcelHeader.Income)) {
                    //收入
                    tempValue.put(AliTripTransferConstants.AliTripVoucherExcelHeader.Income, j);
                } else if (cellData.equals(AliTripTransferConstants.AliTripVoucherExcelHeader.Business_Basic_Order_Number)) {
                    //业务基础订单号
                    tempValue.put(AliTripTransferConstants.AliTripVoucherExcelHeader.Business_Basic_Order_Number, j);
                }
            }

            if (tempValue.size()!=5){
                throw new BusinessException(4001,"数据源文件格式不正，请确认");
            }

            for (int i = 1; i < rowMax; i++) {
//                    Map<String, String> map = new LinkedHashMap<String, String>();
                row = sheet.getRow(i);
                if (row != null) {
                    String paymentType = String.valueOf(row.getCell(tempValue.get(AliTripTransferConstants.AliTripVoucherExcelHeader.Accounting_Type)));
                    if (paymentType.contains(AliTripTransferConstants.AliTripVoucherExcelValue.Online_Payment)) {
                        FinanceCheckTmpEntity tmp = new FinanceCheckTmpEntity();
                        String externalOrderId = String.valueOf(row.getCell(tempValue.get(AliTripTransferConstants.AliTripVoucherExcelHeader.Business_Basic_Order_Number)));
                        String paymentVoucherNo = String.valueOf(row.getCell(tempValue.get(AliTripTransferConstants.AliTripVoucherExcelHeader.Alipay_Transaction_Number)));
                        String payTime = null;
                        try {
                            payTime = row.getCell(tempValue.get(AliTripTransferConstants.AliTripVoucherExcelHeader.Entry_Time)).getLocalDateTimeCellValue().toString();

                        } catch (Exception e) {
                            payTime = String.valueOf(row.getCell(tempValue.get(AliTripTransferConstants.AliTripVoucherExcelHeader.Entry_Time)));
                        }
                        String strPayMoney = String.valueOf(row.getCell(tempValue.get(AliTripTransferConstants.AliTripVoucherExcelHeader.Income)));

                        tmp.setPaymentVoucherNo(paymentVoucherNo);
                        tmp.setExternalOrderId(externalOrderId);
                        tmp.setRelateOrderId(null);
                        BigDecimal payMoney = new BigDecimal(strPayMoney.trim());
                        tmp.setPaymentMoney(payMoney);
                        tmp.setPayTime(payTime);
                        list.add(tmp);
                    }
                } else {
                    break;
                }
            }
        }

        return list;
    }

    private List<FinanceCheckTmpEntity> TcRideVoucherExcel(Workbook wb) {

        Row row = null;
        Sheet sheet = null;
        String cellData = null;

        List<FinanceCheckTmpEntity> list = new ArrayList<FinanceCheckTmpEntity>();
        if (wb != null) {
            //获取第一个sheet
            sheet = wb.getSheetAt(0);
            //获取最大行数
            int rowMax = sheet.getPhysicalNumberOfRows();
            //获取第一行
            row = sheet.getRow(0);
            //获取最大列数
            int colMax = row.getPhysicalNumberOfCells();

            HashMap<String, Integer> tempValue = new HashMap<>();
            for (int j = 0; j < colMax; j++) {
                row = sheet.getRow(0);
                cellData = String.valueOf(row.getCell(j));

                if (cellData.equals(TongChengConstants.AccountExcelHeader.Entry_Time)) {
                    //入账时间
                    tempValue.put(TongChengConstants.AccountExcelHeader.Entry_Time, j);
                } else if (cellData.equals(TongChengConstants.AccountExcelHeader.Transaction_Number)) {
                    //支付宝交易号
                    tempValue.put(TongChengConstants.AccountExcelHeader.Transaction_Number, j);
                } else if (cellData.equals(TongChengConstants.AccountExcelHeader.Income)) {
                    //收入
                    tempValue.put(TongChengConstants.AccountExcelHeader.Income, j);
                } else if (cellData.equals(TongChengConstants.AccountExcelHeader.OrderId)) {
                    //订单号
                    tempValue.put(TongChengConstants.AccountExcelHeader.OrderId, j);
                } else if (cellData.equals(TongChengConstants.AccountExcelHeader.ExternalOrderId)) {
                    //第三方订单号
                    tempValue.put(TongChengConstants.AccountExcelHeader.ExternalOrderId, j);
                }
            }

            if (tempValue.size()!=5){
                throw new BusinessException(4001,"数据源文件格式不正，请确认");
            }

            for (int i = 1; i < rowMax; i++) {

                row = sheet.getRow(i);
                if (row != null) {
                    String externalOrderId = String.valueOf(row.getCell(tempValue.get(TongChengConstants.AccountExcelHeader.ExternalOrderId)));
                    if (StringUtil.isBlank(externalOrderId)==false) {
                        FinanceCheckTmpEntity tmp = new FinanceCheckTmpEntity();
                        String orderId = String.valueOf(row.getCell(tempValue.get(TongChengConstants.AccountExcelHeader.OrderId)));
                        String paymentVoucherNo = String.valueOf(row.getCell(tempValue.get(TongChengConstants.AccountExcelHeader.Transaction_Number)));

                        //String payTime = row.getCell(tempValue.get(TongChengConstants.AccountExcelHeader.Entry_Time)).getLocalDateTimeCellValue().toString();
                        String payTime = null;
                        try {
                            payTime = row.getCell(tempValue.get(TongChengConstants.AccountExcelHeader.Entry_Time)).getLocalDateTimeCellValue().toString();
                        } catch (Exception e) {
                            payTime = String.valueOf(row.getCell(tempValue.get(TongChengConstants.AccountExcelHeader.Entry_Time)));
                        }
                        String strPayMoney = String.valueOf(evaluateCell(row.getCell(tempValue.get(TongChengConstants.AccountExcelHeader.Income))));

                        tmp.setPaymentVoucherNo(paymentVoucherNo);
                        tmp.setExternalOrderId(externalOrderId);
                        tmp.setRelateOrderId(orderId);
                        BigDecimal payMoney = new BigDecimal(strPayMoney.trim());
                        tmp.setPaymentMoney(payMoney);
                        tmp.setPayTime(payTime);
                        list.add(tmp);
                    }

                } else {
                    break;
                }
            }
        }

        return list;
    }

    // 计算单元格的值
    private double evaluateCell(Cell cell) {

        Workbook workbook = cell.getSheet().getWorkbook();

        FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();

        CellValue cellValue = evaluator.evaluate(cell);

        return cellValue.getNumberValue();

    }
}
